<?php

namespace app\common\controller;

use think\facade\Db;
use app\common\utils\Curl;
use think\facade\Log;

class QywxController extends BaseController
{

    protected $token;
    protected $huiHuaToken;
    protected $contactsToken;
    protected $ticket;
    protected $jsapiticket;

    protected function initialize()
    {
        $this->token = $this->getToken();
        $this->huiHuaToken = $this->getHuiHuaToken();
        $this->contactsToken = $this->getContactsToken();
        $this->ticket = $this->getTicket($this->token);
        $this->jsapiticket = $this->getJsapiTicket($this->token);
    }

    /******************************************************************************** 应用授权码的access_token ****************************************************************************************/

    /**
     * 应用授权码的access_token
     */
    protected function getToken()
    {
        //检测本地是否已经拥有access_token，并且检测access_token是否过期
        $accessToken = self::_checkQiYeWeiXinAccessToken();
        if ($accessToken === false) {
            $accessToken = self::_getQiYeWeiXinAccessToken();
            //Log::info('xingxin_token过期了'.json_encode($accessToken));
            return $accessToken['access_token'] ?? '';
        } else {
            //Log::info('沿用本地token'.json_encode($accessToken));
            return $accessToken['access_token'] ?? '';
        }
    }

    /**
     * 应用授权码的access_token是否过期
     * access_token的有效期目前为2小时(7200秒)，需定时刷新。
     * @param $keys  存储token的字段名
     * @return bool
     */
    private static function _checkQiYeWeiXinAccessToken()
    {
        $data = Db::table('xh_common')->where('keys', 'qiyeweixin_token_'.env('qywx.corpid'))->find();
        if ($data) {
            $data = unserialize($data['values']);
            if ($data && time() - $data['time'] < 60 * 60) {
                return $data;
            }
        }
        return false;
    }


    /**
     * 应用授权码的access_token
     * @param $keys  存储token的字段名
     * @param $appid 程序appid
     * @param $appsecret   程序的密钥
     * @return error|string
     */
    private static function _getQiYeWeiXinAccessToken()
    {
        $queryUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.env('qywx.corpid').'&corpsecret='.env('qywx.corpsecret');

        $result = Curl::callWebServer($queryUrl);
        if (!empty($result) && $result['errcode'] == 0) {
            $accessToken['access_token'] = $result['access_token'];
            $accessToken['expires_in'] = $result['expires_in'];
            //我们把token保存在数据库中
            $accessToken['time'] = time();
            $data = ['keys' => 'qiyeweixin_token_'.env('qywx.corpid'), 'values' => serialize($accessToken)];
            $keys = Db::table('xh_common')->where('keys', 'qiyeweixin_token_'.env('qywx.corpid'))->find();
            if (empty($keys)) {
                Db::table('xh_common')->insert($data);
            } else {
                Db::table('xh_common')->save($data);
            }
        }

        return $result;
    }



    /******************************************************************************** 同步通讯录授权码的access_token ****************************************************************************************/

    /**
     * 同步通讯录的access_token
     */
    protected function getContactsToken()
    {
        //检测本地是否已经拥有access_token，并且检测access_token是否过期
        $accessToken = self::_checkContactsAccessToken();
        if ($accessToken === false) {
            $accessToken = self::_getContactsAccessToken();
            return $accessToken['access_token'] ?? '';
        } else {
            return $accessToken['access_token'] ?? '';
        }
    }

    /**
     * 同步通讯录的access_token是否过期
     * access_token的有效期目前为2小时(7200秒)，需定时刷新。
     * @param $keys  存储token的字段名
     * @return bool
     */
    private static function _checkContactsAccessToken()
    {
        $data = Db::table('xh_common')->where('keys', 'qiyeweixin_contacts_token_'.env('qywx.corpid'))->find();
        if ($data) {
            $data = unserialize($data['values']);
            if ($data && time() - $data['time'] < 60 * 60) {
                return $data;
            }
        }
        return false;
    }

    /**
     * 同步通讯录的access_token
     * @param $keys  存储token的字段名
     * @param $appid 程序appid
     * @param $appsecret   程序的密钥
     * @return error|string
     */
    private static function _getContactsAccessToken()
    {
        $queryUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.env('qywx.corpid').'&corpsecret='.env('qywx.contactsSecret');

        $result = Curl::callWebServer($queryUrl);
        if (!empty($result) && $result['errcode'] == 0) {
            $accessToken['access_token'] = $result['access_token'];
            $accessToken['expires_in'] = $result['expires_in'];
            //我们把token保存在数据库中
            $accessToken['time'] = time();
            $data = ['keys' => 'qiyeweixin_contacts_token_'.env('qywx.corpid'), 'values' => serialize($accessToken)];
            $keys = Db::table('xh_common')->where('keys', 'qiyeweixin_contacts_token_'.env('qywx.corpid'))->find();
            if (empty($keys)) {
                Db::table('xh_common')->insert($data);
            } else {
                Db::table('xh_common')->save($data);
            }
        }

        return $result;
    }
    
    /******************************************************************************** 会话授权码的access_token ****************************************************************************************/

    protected function getHuiHuaToken()
    {
        //检测本地是否已经拥有access_token，并且检测access_token是否过期
        $accessToken = self::_checkQiWeiHuiHuaCunDangAccessToken();
        if ($accessToken === false) {
            $accessToken = self::_getQiWeiHuiHuaCunDangAccessToken();
            return $accessToken['access_token'] ?? '';
        } else {
            return $accessToken['access_token'] ?? '';
        }
    }

    private static function _checkQiWeiHuiHuaCunDangAccessToken()
    {
        $data = Db::table('xh_common')->where('keys', 'huihuacundang_token_'.env('qywx.corpid'))->find();
        if ($data) {
            $data = unserialize($data['values']);
            if ($data && time() - $data['time'] < 60 * 60) {
                return $data;
            }
        }
        return false;
    }
    
    /**
     * 会话存档获取access_token
     * @param $keys  存储token的字段名
     * @param $appid 程序appid
     * @param $appsecret   程序的密钥
     * @return error|string
     */
    private static function _getQiWeiHuiHuaCunDangAccessToken()
    {
        $queryUrl = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.env('qywx.corpid').'&corpsecret='.env('qywx.huihuaSecret');

        $result = Curl::callWebServer($queryUrl);
        if (!empty($result) && $result['errcode'] == 0) {
            $accessToken['access_token'] = $result['access_token'];
            $accessToken['expires_in'] = $result['expires_in'];
            //我们把token保存在数据库中
            $accessToken['time'] = time();
            $data = ['keys' => 'huihuacundang_token_'.env('qywx.corpid'), 'values' => serialize($accessToken)];
            $keys = Db::table('xh_common')->where('keys', 'huihuacundang_token_'.env('qywx.corpid'))->find();
            if (empty($keys)) {
                Db::table('xh_common')->insert($data);
            } else {
                Db::table('xh_common')->save($data);
            }
        }

        return $result;
    }
    
    
    /******************************************************************************** jsapi的access_token ****************************************************************************************/

    // jsapi_ticket 企业签名
    // 企业微信企业jsapi_ticket
    protected function getTicket($token)
    {
        //检测本地是否已经拥有access_token，并且检测access_token是否过期
        $jsapiTicket = self::_checkQiYeWeiXinTicket();
        if ($jsapiTicket === false) {
            $jsapiTicket = self::_getQiYeWeiXinTicket($token);
            return $jsapiTicket['ticket'] ?? '';
        } else {
            return $jsapiTicket['ticket'] ?? '';
        }
    }

    private static function _checkQiYeWeiXinTicket()
    {
        $data = Db::table('xh_common')->where(array('keys' => 'qiyeweixin_ticket_'.env('qywx.corpid')))->find();
        if ($data) {
            $data = unserialize($data['values']);
            if ($data && time() - $data['time'] < 60 * 60) {
                return $data;
            }
        }
        return false;
    }

    private static function _getQiYeWeiXinTicket($token)
    {
        $queryUrl = 'https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token='.$token;

        $result = Curl::callWebServer($queryUrl);
        if (!empty($result) && $result['errcode'] == 0) {
            $accessToken['ticket'] = $result['ticket'];
            $accessToken['expires_in'] = $result['expires_in'];
            $accessToken['time'] = time();
            $data = ['keys' => 'qiyeweixin_ticket_'.env('qywx.corpid'), 'values' => serialize($accessToken)];
            $keys = Db::table('xh_common')->where('keys', 'qiyeweixin_ticket_'.env('qywx.corpid'))->find();
            if (empty($keys)) {
                Db::table('xh_common')->insert($data);
            } else {
                Db::table('xh_common')->save($data);
            }
            //Db::table('xh_common')->save(['keys' => 'qiyeweixin_ticket_'.env('qywx.corpid'), 'values' => serialize($accessToken)]);
        }
        return $result;
    }



    // jsapi_ticket 应用签名
    // 企业微信应用jsapi_ticket
    protected function getJsapiTicket($token)
    {
        //检测本地是否已经拥有access_token，并且检测access_token是否过期
        $jsapiTicket = self::_checkQiYeWeiXinJsApiTicket();
        if ($jsapiTicket === false) {
            $jsapiTicket = self::_getQiYeWeiXinJsApiTicket($token);
            return $jsapiTicket['ticket'] ?? '';
        } else {
            return $jsapiTicket['ticket'] ?? '';
        }
    }

    private static function _checkQiYeWeiXinJsApiTicket()
    {
        $data = Db::table('xh_common')->where(array('keys' => 'qiyeweixin_jsapi_ticket_'.env('qywx.corpid')))->find();
        if ($data) {
            $data = unserialize($data['values']);
            if ($data && time() - $data['time'] < 60 * 60) {
                return $data;
            }
        }
        return false;
    }

    private static function _getQiYeWeiXinJsApiTicket($token)
    {
        $queryUrl = 'https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token='.$token.'&type=agent_config';

        $result = Curl::callWebServer($queryUrl);
        if (!empty($result) && $result['errcode'] == 0) {
            $accessToken['ticket'] = $result['ticket'];
            $accessToken['expires_in'] = $result['expires_in'];
            $accessToken['time'] = time();
            $data = ['keys' => 'qiyeweixin_jsapi_ticket_'.env('qywx.corpid'), 'values' => serialize($accessToken)];
            $keys = Db::table('xh_common')->where('keys', 'qiyeweixin_jsapi_ticket_'.env('qywx.corpid'))->find();
            if (empty($keys)) {
                Db::table('xh_common')->insert($data);
            } else {
                Db::table('xh_common')->save($data);
            }
        }
        //Db::table('xh_common')->save(['keys' => 'qiyeweixin_jsapi_ticket_'.env('qywx.corpid'), 'values' => serialize($accessToken)]);
        return $result;
    }

    /******************************************************************************** 工具 ****************************************************************************************/

    /**
     * 生成随机字符串 16位
     */
    protected function createNonceStr($length = 16)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /******************************************************************************** 其他 ****************************************************************************************/


    /**
     * 个人企微标签
     */
    protected function tags($externalUserid,$userid)
    {
        $url = 'https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token='.$this->token.'&external_userid='.$externalUserid;
        $result = Curl::callWebServer($url);
        $getTag = array();
        foreach ($result['follow_user'] as $key => $value) {
            if ($value['userid'] == $userid) {
                $getTag[] = $value['tags'];
            }
        }
        return $getTag;
    }

}